home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume20 / etherlib / part01 next >
Encoding:
Internet Message Format  |  1989-10-24  |  60.8 KB

  1. Subject:  v20i058:  User-level interface to Ethernet, Part01/03
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Alexander Dupuy <dupuy@cs.columbia.edu>
  7. Posting-number: Volume 20, Issue 58
  8. Archive-name: etherlib/part01
  9.  
  10. This ethernet access library is a part of the Columbia Netmate project
  11. which is being released as a useful component in its own right.
  12.  
  13. These functions provide access to the raw ethernet for user-level
  14. programs.  On Suns, they are implemented using NIT(4p) (network interface
  15. tap).  While they do not provide the full functionality of NIT, these
  16. functions do run on both the socket- and streams-based NIT
  17. implementations.  On Ultrix systems, they are implemented using DLI (data
  18. link interface).  On Berkeley systems, they are implemented using the
  19. Stanford enetfilter available as user-contributed software in the 4.3 BSD
  20. release.
  21.  
  22. These functions are not designed to be used for ethernet monitoring, but rather
  23. for programs implementing ethernet protocols such as RARP, or the Ethernet
  24. configuration test protocol.
  25.  
  26. It comes with a manual page, and both a GNU makefile and a regular one.
  27.  
  28. If you are on a BSD system with the enetfilter, you will have to create
  29. some new device files before you can build or use this library.  Because
  30. there is no way to map between the interface names ("il0", "de0", etc.)
  31. used by most programs and the old enetfilter device names (/dev/enet0,
  32. /dev/eneta0, etc.), this library uses a different convention for
  33. enetfilter device names, using device files in the /dev/enet/ directory.
  34.  
  35. #! /bin/sh
  36. # This is a shell archive.  Remove anything before this line, then unpack
  37. # it by saving it into a file and typing "sh file".  To overwrite existing
  38. # files, type "sh file -c".  You can also feed this as standard input via
  39. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  40. # will see the following message at the end:
  41. #        "End of archive 1 (of 3)."
  42. # Contents:  ./GNUmake.config ./GNUmakefile ./ReadMe
  43. #   ./src ./src/ReadMe ./src/dliaddr.c ./src/dliintaddr.c
  44. #   ./src/dliread.c ./src/dlireadv.c ./src/dliself.c ./src/dliwrite.c
  45. #   ./src/dliwritev.c ./src/enetaddr.c ./src/enetblock.c
  46. #   ./src/enetintaddr.c ./src/enetself.c ./src/enetwrite.c
  47. #   ./src/enetwritev.c ./src/ethera2e.c ./src/etheraddr.c
  48. #   ./src/etherblock.c ./src/ethere2a.c ./src/etherlocal.c
  49. #   ./src/etherread.c ./src/etherreadv.c ./src/libether.h
  50. #   ./src/nit3intaddr.c ./src/nit3read.c ./src/nit3readv.c
  51. #   ./src/nit3self.c ./src/nit3write.c ./src/nit3writev.c
  52. #   ./src/nit4intaddr.c ./src/nit4self.c ./src/nit4write.c
  53. #   ./src/nit4writev.c ./src/nitaddr.c ./system ./tests MANIFEST
  54. # Wrapped by rsalz@papaya.bbn.com on Wed Oct 25 16:37:29 1989
  55. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  56. if test -f './GNUmake.config' -a "${1}" != "-c" ; then 
  57.   echo shar: Will not clobber existing file \"'./GNUmake.config'\"
  58. else
  59. echo shar: Extracting \"'./GNUmake.config'\" \(1799 characters\)
  60. sed "s/^X//" >'./GNUmake.config' <<'END_OF_FILE'
  61. X#
  62. X# Build flags which are used by various components
  63. X#
  64. X
  65. Xifeq ($(SYSTEM),)
  66. X
  67. XSYSTEM := $(strip $(shell PATH=$$PATH:.:..:../..:../../.. system ))
  68. X
  69. X
  70. X# Compilation parameters
  71. X# (don't try to use gcc if the machine isn't supported yet)
  72. X# don't use gcc on Sun-4 until we resolve structure pass/return incompatibility
  73. X
  74. Xifneq ($(findstring ibmrt,$(SYSTEM)),ibmrt)
  75. Xifneq ($(findstring mipsel,$(SYSTEM)),mipsel)
  76. Xifneq ($(findstring sun4,$(SYSTEM)),sun4)
  77. XCC := gcc
  78. Xendif
  79. Xendif
  80. Xendif
  81. X
  82. X#
  83. X# Sun-3 floating-point options; replace 68881 with soft or fpa as appropriate
  84. X#
  85. X
  86. Xifeq ($(findstring sun3,$(SYSTEM)),sun3)
  87. X
  88. XFLOAT_OPTION = f68881
  89. X
  90. Xifeq ($(findstring os4,$(SYSTEM)),os4)
  91. X
  92. XFLIB = /usr/lib/$(FLOAT_OPTION).il
  93. X
  94. Xelse
  95. X
  96. XFLIB = /usr/lib/$(FLOAT_OPTION)/libm.il
  97. X
  98. Xendif
  99. X
  100. Xendif
  101. X
  102. XOPT = -g
  103. XOPTG = -g -W
  104. X
  105. Xifeq ($(findstring os4,$(SYSTEM)),os4)
  106. Xifeq ($(findstring -g,$(OPTG)),-g)
  107. Xifeq ($(findstring gcc,$(CC)),gcc)
  108. Xoverride LDFLAGS := -g -static
  109. Xelse
  110. Xoverride LDFLAGS := -g -Bstatic
  111. Xendif
  112. Xendif
  113. Xendif
  114. X
  115. XDEFINES = 
  116. X
  117. X
  118. X# Listing variables and flags
  119. X
  120. XTROFF = ptroff
  121. XVGRIND = vgrind
  122. X
  123. XGRIND = $(VGRIND) -d vgrindefs
  124. X
  125. X
  126. X# Installation tools
  127. X
  128. XINSTALL=install -c
  129. X
  130. Xifeq ($(findstring os4,$(SYSTEM)),os4)
  131. XRANLIB=ranlib -t
  132. Xelse
  133. XRANLIB=ranlib
  134. Xendif
  135. X
  136. X
  137. X# Installation locations
  138. X
  139. XMANDIR = /usr/local/man
  140. XBINDIR = /usr/local/bin
  141. XLIBDIR = /usr/local/lib
  142. XINCDIR = /usr/local/include
  143. X
  144. Xendif
  145. X
  146. X
  147. X# Pattern rules
  148. X
  149. X%.ps: %.c
  150. X    $(VGRIND) -lC -t $< > $@
  151. X
  152. X%.ps: %.h
  153. X    $(VGRIND) -lC -t $< > $@
  154. X
  155. X# Installation pattern rules
  156. X
  157. X%/bin: %
  158. X    mkdir $@
  159. X
  160. X$(BINDIR)/%: %
  161. X    $(INSTALL) $< $@
  162. X
  163. X%/lib: %
  164. X    mkdir $@
  165. X
  166. X$(LIBDIR)/%: %
  167. X    $(INSTALL) $< $@
  168. X    $(RANLIB) $@
  169. X    @chmod -x $@
  170. X
  171. X%/include: %
  172. X    mkdir $@
  173. X
  174. X$(INCDIR)/%: %
  175. X    $(INSTALL) $< $@
  176. X    @chmod -x $@
  177. X
  178. X%/man: %
  179. X    mkdir $@
  180. X
  181. X$(MANDIR)/man1/%: %
  182. X    $(INSTALL) $< $@
  183. X    @chmod -x $@
  184. X
  185. X$(MANDIR)/man3/%: %
  186. X    $(INSTALL) $< $@
  187. X    @chmod -x $@
  188. END_OF_FILE
  189. if test 1799 -ne `wc -c <'./GNUmake.config'`; then
  190.     echo shar: \"'./GNUmake.config'\" unpacked with wrong size!
  191. fi
  192. # end of './GNUmake.config'
  193. fi
  194. if test -f './GNUmakefile' -a "${1}" != "-c" ; then 
  195.   echo shar: Will not clobber existing file \"'./GNUmakefile'\"
  196. else
  197. echo shar: Extracting \"'./GNUmakefile'\" \(621 characters\)
  198. sed "s/^X//" >'./GNUmakefile' <<'END_OF_FILE'
  199. X#
  200. X# GNU makefile for ethernet library
  201. X#
  202. X
  203. Xinclude GNUmake.config
  204. X
  205. XOPTG := -O $(OPTG)
  206. XOPT := -O
  207. XDEFINES =
  208. X
  209. X# This doesn't do anything - it just hands it off to the subdirectory
  210. X
  211. X.PHONY: all install lint noise listing clean cleanlists realclean
  212. X
  213. Xall install ethertest ctp: $(SYSTEM)
  214. X    $(MAKE) -C $(SYSTEM) -f ../GNUmake.mk $@
  215. X
  216. Xlint noise listing:
  217. X    $(MAKE) -C src -f ../GNUmake.mk $@
  218. X
  219. Xclean: $(SYSTEM)
  220. X    $(MAKE) -C $(SYSTEM) -f ../GNUmake.mk $@
  221. X
  222. Xrealclean: $(SYSTEM)
  223. X    $(MAKE) -C $(SYSTEM) -f ../GNUmake.mk $@
  224. X    $(MAKE) -C src -f ../GNUmake.mk $@
  225. X
  226. X$(SYSTEM):
  227. X    mkdir $(SYSTEM)
  228. X
  229. X.DEFAULT:
  230. X    $(MAKE) -C $(SYSTEM) -f ../GNUmake.mk $@
  231. END_OF_FILE
  232. if test 621 -ne `wc -c <'./GNUmakefile'`; then
  233.     echo shar: \"'./GNUmakefile'\" unpacked with wrong size!
  234. fi
  235. # end of './GNUmakefile'
  236. fi
  237. if test -f './ReadMe' -a "${1}" != "-c" ; then 
  238.   echo shar: Will not clobber existing file \"'./ReadMe'\"
  239. else
  240. echo shar: Extracting \"'./ReadMe'\" \(644 characters\)
  241. sed "s/^X//" >'./ReadMe' <<'END_OF_FILE'
  242. X
  243. XThis is the source tree for the ethernet interface library.
  244. X
  245. XGNUmakefile
  246. X
  247. X    is the master makefile for the ethernet interface library.
  248. X
  249. XGNUmake.mk
  250. X
  251. X    is used as a common makefile for the architecture-specific
  252. X    subdirectories.
  253. X
  254. Xether.3n
  255. X
  256. X    manual page describing the library routines
  257. X
  258. XInstructions
  259. X
  260. X    are instructions for building this library.
  261. X
  262. XSunBugs
  263. X
  264. X    describes several bugs in the Sun 4.0 NIT interface
  265. X
  266. XThere are the following subdirectories
  267. X
  268. X    src        contains the sources
  269. X    tests        contains the source for test programs
  270. X    enet        contains sources for Stanford enetfilter
  271. X
  272. X    sun3        have object files for various architectures
  273. X    sun3-os4
  274. X    sun4-os4
  275. X    etc.
  276. END_OF_FILE
  277. if test 644 -ne `wc -c <'./ReadMe'`; then
  278.     echo shar: \"'./ReadMe'\" unpacked with wrong size!
  279. fi
  280. # end of './ReadMe'
  281. fi
  282. if test ! -d './src' ; then
  283.     echo shar: Creating directory \"'./src'\"
  284.     mkdir './src'
  285. fi
  286. if test -f './src/ReadMe' -a "${1}" != "-c" ; then 
  287.   echo shar: Will not clobber existing file \"'./src/ReadMe'\"
  288. else
  289. echo shar: Extracting \"'./src/ReadMe'\" \(1021 characters\)
  290. sed "s/^X//" >'./src/ReadMe' <<'END_OF_FILE'
  291. X
  292. XThis is the source subtree for the ethernet interface library.
  293. X
  294. XMakefile
  295. X
  296. X    is a no-frills makefile for the ethernet interface library, so that it
  297. X    can be distributed separately, and used with any make.  If you have GNU
  298. X    make, you should be using the GNUmakefile in the parent directory.
  299. X
  300. Xether.h
  301. X
  302. X    is the external interface header file for installation in /usr/include.
  303. X
  304. Xlibether.h
  305. X
  306. X    is the internal header file, for use by the library only.
  307. X
  308. Xetherblock.c
  309. Xetherints.c
  310. X
  311. X    are generic, and should work on any system with Berkeley sockets.
  312. X
  313. Xetherread.c
  314. X
  315. X    is somewhat generic, and works on SunOS 4.x and BSD+enetfilter systems.
  316. X
  317. Xnitaddr.c
  318. X
  319. X    has generic NIT code, and should work on any system with NIT.
  320. X
  321. Xnit4open.c
  322. X
  323. X    has streams-based NIT code, and works only on SunOS 4.x systems.
  324. X
  325. Xnit3open.c
  326. X
  327. X    has socket-based NIT code, and works only on SunOS 3.x systems.
  328. X
  329. Xdliopen.c
  330. X
  331. X    has Ultrix DLI code, and works only on Ultrix systems.
  332. X
  333. Xenetaddr.c
  334. Xenetopen.c
  335. X
  336. X    have Stanford enetfilter code, and work only on BSD+enetfilter systems.
  337. END_OF_FILE
  338. if test 1021 -ne `wc -c <'./src/ReadMe'`; then
  339.     echo shar: \"'./src/ReadMe'\" unpacked with wrong size!
  340. fi
  341. # end of './src/ReadMe'
  342. fi
  343. if test -f './src/dliaddr.c' -a "${1}" != "-c" ; then 
  344.   echo shar: Will not clobber existing file \"'./src/dliaddr.c'\"
  345. else
  346. echo shar: Extracting \"'./src/dliaddr.c'\" \(1468 characters\)
  347. sed "s/^X//" >'./src/dliaddr.c' <<'END_OF_FILE'
  348. X/* $Id: dliaddr.c,v 2.0 89/10/20 19:01:26 dupuy Exp $ */
  349. X
  350. X#include <sys/param.h>            /* NOFILE */
  351. X#include <sys/ioctl.h>            /* ioctl */
  352. X#include <sys/socket.h>            /* sockaddr_dl (sockaddr) */
  353. X
  354. X#include <net/if.h>            /* ifdevea */
  355. X#include <netinet/in.h>            /* (ether_header) (in_addr) */
  356. X#include <netinet/if_ether.h>        /* sockaddr_dl (ether_header)  */
  357. X#include <netdnet/dli_var.h>        /* sockaddr_dl */
  358. X
  359. X#include "libether.h"
  360. X
  361. Xextern struct sockaddr_dl _ether_sockaddrs[NOFILE];
  362. X
  363. X#define sad (_ether_sockaddrs[fd])
  364. X
  365. X
  366. Xstatic void
  367. Xdevid_to_name (name, devid)
  368. Xchar *name;
  369. Xstruct dli_devid *devid;
  370. X{
  371. X    register int i;
  372. X
  373. X    for (i = 0; devid->dli_devname[i]; i++)
  374. X    name[i] = devid->dli_devname[i];
  375. X
  376. X    name[i++] = '0' + devid->dli_devnumber;
  377. X
  378. X    name[i] = '\0';
  379. X}
  380. X
  381. X
  382. X/*
  383. X * Returns the local ethernet address for the ethernet interface on the file
  384. X * descriptor fd.  The result is stored in the structure given by address; if
  385. X * none is given, malloc is used to allocate space.
  386. X */
  387. X
  388. Xether_addr *
  389. Xether_address (fd, address)
  390. Xint fd;
  391. Xether_addr *address;
  392. X{
  393. X    struct ifdevea ifd;
  394. X
  395. X    devid_to_name (ifd.ifr_name, &sad.dli_device);
  396. X
  397. X    if (ioctl (fd, SIOCRPHYSADDR, (char *) &ifd) < 0)
  398. X    {
  399. X#ifdef DEBUG
  400. X    perror ("ether_address: ioctl SIOCRPHYSADDR");
  401. X#endif
  402. X    return (0);
  403. X    }
  404. X
  405. X    if (address == 0)
  406. X    address = (ether_addr *) malloc (sizeof (ether_addr));
  407. X
  408. X    if (address != 0)
  409. X    bcopy ((char *) ifd.current_pa, (char *) address, sizeof (ether_addr));
  410. X
  411. X    return (address);
  412. X}
  413. END_OF_FILE
  414. if test 1468 -ne `wc -c <'./src/dliaddr.c'`; then
  415.     echo shar: \"'./src/dliaddr.c'\" unpacked with wrong size!
  416. fi
  417. # end of './src/dliaddr.c'
  418. fi
  419. if test -f './src/dliintaddr.c' -a "${1}" != "-c" ; then 
  420.   echo shar: Will not clobber existing file \"'./src/dliintaddr.c'\"
  421. else
  422. echo shar: Extracting \"'./src/dliintaddr.c'\" \(821 characters\)
  423. sed "s/^X//" >'./src/dliintaddr.c' <<'END_OF_FILE'
  424. X/* $Id: dliintaddr.c,v 2.1 89/10/23 15:41:58 dupuy Exp $ */
  425. X
  426. X#include <errno.h>
  427. X
  428. Xextern int errno;
  429. X
  430. X#include "libether.h"
  431. X
  432. X/*
  433. X * Returns the local ethernet address for the ethernet interface.  The result
  434. X * is stored in the structure given by address; if none is given, malloc is
  435. X * used to allocate space.
  436. X */
  437. X
  438. Xether_addr *
  439. Xether_intfaddr (intf, address)
  440. Xchar *intf;
  441. Xether_addr *address;
  442. X{
  443. X    int fd;
  444. X    unsigned short proto = 0xffff;
  445. X    int saved_errno;
  446. X
  447. X    do
  448. X    if ((fd = ether_open (intf, proto--, (ether_addr *) 0)) < 0)
  449. X    {
  450. X        if (errno == EADDRINUSE)
  451. X        continue;
  452. X        return (0);
  453. X    }                /* constant argument to NOT ??? */
  454. X    while (fd < 0 && proto >= ETHER_MINTYPE);
  455. X
  456. X    address = ether_address (fd, address);
  457. X
  458. X    saved_errno = errno;
  459. X    (void) close (fd);
  460. X    errno = saved_errno;
  461. X
  462. X    return (address);
  463. X}
  464. END_OF_FILE
  465. if test 821 -ne `wc -c <'./src/dliintaddr.c'`; then
  466.     echo shar: \"'./src/dliintaddr.c'\" unpacked with wrong size!
  467. fi
  468. # end of './src/dliintaddr.c'
  469. fi
  470. if test -f './src/dliread.c' -a "${1}" != "-c" ; then 
  471.   echo shar: Will not clobber existing file \"'./src/dliread.c'\"
  472. else
  473. echo shar: Extracting \"'./src/dliread.c'\" \(1891 characters\)
  474. sed "s/^X//" >'./src/dliread.c' <<'END_OF_FILE'
  475. X/* $Id: dliread.c,v 2.1 89/10/23 15:42:04 dupuy Exp $ */
  476. X
  477. X#include <sys/param.h>            /* NOFILE */
  478. X#include <sys/socket.h>            /* sockaddr_dl (sockaddr) */
  479. X
  480. X#include <net/if.h>            /* ifdevea */
  481. X#include <netinet/in.h>            /* (ether_header) (in_addr) */
  482. X#include <netinet/if_ether.h>        /* sockaddr_dl (ether_header) */
  483. X#include <netdnet/dli_var.h>        /* sockaddr_dl */
  484. X
  485. X#include <errno.h>            /* EWOULDBLOCK */
  486. X
  487. X#include "libether.h"
  488. X
  489. Xextern ether_addr _ether_multi_addrs[NOFILE];
  490. X
  491. X/*
  492. X * Reads and returns a single packet, filling in all fields.  If pktbuf is
  493. X * NULL, a buffer is allocated for it.    If pktbuf is not NULL, the function
  494. X * assumes that pktbuf is large enough to hold pktlen bytes.  Has to do
  495. X * address checking, since we are operating in DLI_EXCLUSIVE mode.
  496. X */
  497. X
  498. Xint
  499. Xether_read (fd, packet)
  500. Xint fd;
  501. Xether_packet *packet;
  502. X{
  503. X    struct sockaddr_dl from;
  504. X    int alen;
  505. X    int count;
  506. X    char *dest;
  507. X
  508. X    if (packet->pktbuf == 0)
  509. X    {
  510. X    packet->pktlen = ETHER_MAX;
  511. X    if ((packet->pktbuf = (char *) malloc ((unsigned) ETHER_MAX)) == 0)
  512. X        return (-1);
  513. X    }
  514. X
  515. X    from.dli_family = AF_DLI;
  516. X    alen = sizeof (from);
  517. X
  518. X    do                    /* ignore bogus multicast packets */
  519. X    {
  520. X    if ((count = recvfrom (fd, packet->pktbuf, (int) packet->pktlen, 0,
  521. X                   (struct sockaddr *) &from, &alen)) < 0)
  522. X    {
  523. X        if (errno == EWOULDBLOCK)
  524. X        errno = EAGAIN;
  525. X        return (-1);
  526. X    }
  527. X
  528. X    dest = (char *) from.choose_addr.dli_eaddr.dli_dest;
  529. X    }
  530. X    while (address_check (dest));    /* constant argument to NOT ??? */
  531. X
  532. X    bcopy (dest, (char *) &packet->dest, sizeof (ether_addr));
  533. X    bcopy ((char *) from.choose_addr.dli_eaddr.dli_target,
  534. X       (char *) &packet->src, sizeof (ether_addr));
  535. X    packet->type[0] = (from.choose_addr.dli_eaddr.dli_protype & 0xff00) >> 8;
  536. X    packet->type[1] = from.choose_addr.dli_eaddr.dli_protype & 0xff;
  537. X
  538. X    if (packet->pktlen > count)
  539. X    packet->pktlen = count;
  540. X
  541. X    return (count);
  542. X}
  543. END_OF_FILE
  544. if test 1891 -ne `wc -c <'./src/dliread.c'`; then
  545.     echo shar: \"'./src/dliread.c'\" unpacked with wrong size!
  546. fi
  547. # end of './src/dliread.c'
  548. fi
  549. if test -f './src/dlireadv.c' -a "${1}" != "-c" ; then 
  550.   echo shar: Will not clobber existing file \"'./src/dlireadv.c'\"
  551. else
  552. echo shar: Extracting \"'./src/dlireadv.c'\" \(1664 characters\)
  553. sed "s/^X//" >'./src/dlireadv.c' <<'END_OF_FILE'
  554. X/* $Id: dlireadv.c,v 2.1 89/10/23 15:42:06 dupuy Exp $ */
  555. X
  556. X#include <sys/param.h>            /* NOFILE */
  557. X#include <sys/socket.h>            /* sockaddr_dl (sockaddr) */
  558. X#include <sys/uio.h>            /* iovec */
  559. X
  560. X#include <net/if.h>            /* ifdevea */
  561. X#include <netinet/in.h>            /* (ether_header) (in_addr) */
  562. X#include <netinet/if_ether.h>        /* sockaddr_dl (ether_header) */
  563. X#include <netdnet/dli_var.h>        /* sockaddr_dl */
  564. X
  565. X#include <errno.h>            /* EWOULDBLOCK */
  566. X
  567. X#include "libether.h"
  568. X
  569. Xextern ether_addr _ether_multi_addrs[NOFILE];
  570. X
  571. X
  572. X/*
  573. X * Reads and returns a single packet, filling in all fields.  Has to do
  574. X * address checking, since we are operating in DLI_EXCLUSIVE mode.
  575. X */
  576. X
  577. Xint
  578. Xether_readv (fd, packet)
  579. Xint fd;
  580. Xether_vec *packet;
  581. X{
  582. X    struct sockaddr_dl from;
  583. X    struct msghdr msg;
  584. X    int count;
  585. X    char *dest;
  586. X
  587. X    from.dli_family = AF_DLI;
  588. X    msg.msg_iov = packet->iov;
  589. X    msg.msg_iovlen = packet->iovcnt;
  590. X    msg.msg_name = (caddr_t) &from;
  591. X    msg.msg_namelen = sizeof (from);
  592. X    msg.msg_accrights = 0;
  593. X    msg.msg_accrightslen = 0;
  594. X
  595. X    do                    /* ignore bogus multicast packets */
  596. X    {
  597. X    if ((count = recvmsg (fd, &msg, 0)) < 0)
  598. X    {
  599. X        if (errno == EWOULDBLOCK)
  600. X        errno = EAGAIN;
  601. X        return (-1);
  602. X    }
  603. X
  604. X    dest = (char *) from.choose_addr.dli_eaddr.dli_dest;
  605. X    }
  606. X    while (address_check (dest));    /* constant argument to NOT ??? */
  607. X
  608. X    bcopy (dest, (char *) &packet->dest, sizeof (ether_addr));
  609. X    bcopy ((char *) from.choose_addr.dli_eaddr.dli_target,
  610. X       (char *) &packet->src, sizeof (ether_addr));
  611. X    packet->type[0] = (from.choose_addr.dli_eaddr.dli_protype & 0xff00) >> 8;
  612. X    packet->type[1] = from.choose_addr.dli_eaddr.dli_protype & 0xff;
  613. X
  614. X    return (count);
  615. X}
  616. END_OF_FILE
  617. if test 1664 -ne `wc -c <'./src/dlireadv.c'`; then
  618.     echo shar: \"'./src/dlireadv.c'\" unpacked with wrong size!
  619. fi
  620. # end of './src/dlireadv.c'
  621. fi
  622. if test -f './src/dliself.c' -a "${1}" != "-c" ; then 
  623.   echo shar: Will not clobber existing file \"'./src/dliself.c'\"
  624. else
  625. echo shar: Extracting \"'./src/dliself.c'\" \(1415 characters\)
  626. sed "s/^X//" >'./src/dliself.c' <<'END_OF_FILE'
  627. X/* $Id: dliself.c,v 2.0 89/10/20 19:01:55 dupuy Exp $ */
  628. X
  629. X#include <sys/param.h>            /* NOFILE */
  630. X#include <sys/socket.h>            /* sockaddr_dl (sockaddr) */
  631. X
  632. X#include <net/if.h>            /* (ether_header) (ifnet) */
  633. X#include <netinet/in.h>            /* (ether_header) (in_addr) */
  634. X#include <netinet/if_ether.h>        /* sockaddr_dl (ether_header) */
  635. X#include <netdnet/dli_var.h>        /* sockaddr_dl */
  636. X
  637. Xextern struct sockaddr_dl _ether_sockaddrs[NOFILE];
  638. X
  639. X#define sad (_ether_sockaddrs[fd])
  640. X
  641. X/*
  642. X * Most, but not all, VAX interfaces, loopback packets.     The Ultrix drivers
  643. X * for the rest try (with varying degrees of success) to compensate for that
  644. X * as far as broadcast packets go.  The ec (3com) driver does it only for IP
  645. X * packets, and does not support multicast, and seems to be unsupported by
  646. X * DEC.
  647. X */
  648. X
  649. Xstatic char *softloops[] = {"ec", "qe", "se"};
  650. X
  651. Xint
  652. Xether_send_self (fd)
  653. Xint fd;
  654. X{
  655. X    unsigned char *devname = sad.dli_device.dli_devname;
  656. X    int i;
  657. X
  658. X    for (i = 0; i < sizeof (softloops) / sizeof (softloops[0]); i++)
  659. X    if (!strcmp ((char *) devname, softloops[i]))
  660. X        return (0);
  661. X
  662. X    return (1);                /* default to true */
  663. X}
  664. X
  665. Xint
  666. Xether_mcast_self (fd)
  667. Xint fd;
  668. X{
  669. X    return (ether_send_self (fd));
  670. X}
  671. X
  672. Xint
  673. Xether_bcast_self (fd)
  674. Xint fd;
  675. X{
  676. X    unsigned char *devname = sad.dli_device.dli_devname;
  677. X
  678. X    if (!strcmp ((char *) devname, "ec"))
  679. X    return (0);            /* the ec driver is broken... */
  680. X
  681. X    return (1);                /* default to true */
  682. X}
  683. END_OF_FILE
  684. if test 1415 -ne `wc -c <'./src/dliself.c'`; then
  685.     echo shar: \"'./src/dliself.c'\" unpacked with wrong size!
  686. fi
  687. # end of './src/dliself.c'
  688. fi
  689. if test -f './src/dliwrite.c' -a "${1}" != "-c" ; then 
  690.   echo shar: Will not clobber existing file \"'./src/dliwrite.c'\"
  691. else
  692. echo shar: Extracting \"'./src/dliwrite.c'\" \(971 characters\)
  693. sed "s/^X//" >'./src/dliwrite.c' <<'END_OF_FILE'
  694. X/* $Id: dliwrite.c,v 2.1 89/10/23 15:42:09 dupuy Exp $ */
  695. X
  696. X#include <sys/param.h>            /* NOFILE */
  697. X#include <sys/socket.h>            /* sockaddr_dl (sockaddr) */
  698. X
  699. X#include <net/if.h>            /* ifdevea */
  700. X#include <netinet/in.h>            /* (ether_header) (in_addr) */
  701. X#include <netinet/if_ether.h>        /* sockaddr_dl (ether_header) */
  702. X#include <netdnet/dli_var.h>        /* sockaddr_dl */
  703. X
  704. X#include <errno.h>            /* EWOULDBLOCK */
  705. X
  706. X#include "libether.h"
  707. X
  708. Xextern struct sockaddr_dl _ether_sockaddrs[NOFILE];
  709. X
  710. X#define sad (_ether_sockaddrs[fd])
  711. X
  712. X/*
  713. X * Writes a single packet, filling src and type fields.
  714. X */
  715. X
  716. Xint
  717. Xether_write (fd, packet)
  718. Xint fd;
  719. Xether_packet *packet;
  720. X{
  721. X    int result;
  722. X
  723. X    bcopy ((char *) &packet->dest,
  724. X       (char *) sad.choose_addr.dli_eaddr.dli_target, DLI_EADDRSIZE);
  725. X
  726. X    result = sendto (fd, packet->pktbuf, (int) packet->pktlen, 0,
  727. X             (struct sockaddr *) &sad, sizeof (struct sockaddr_dl));
  728. X
  729. X    if (result < 0 && errno == EWOULDBLOCK)
  730. X    errno = EAGAIN;
  731. X
  732. X    return (result);
  733. X}
  734. END_OF_FILE
  735. if test 971 -ne `wc -c <'./src/dliwrite.c'`; then
  736.     echo shar: \"'./src/dliwrite.c'\" unpacked with wrong size!
  737. fi
  738. # end of './src/dliwrite.c'
  739. fi
  740. if test -f './src/dliwritev.c' -a "${1}" != "-c" ; then 
  741.   echo shar: Will not clobber existing file \"'./src/dliwritev.c'\"
  742. else
  743. echo shar: Extracting \"'./src/dliwritev.c'\" \(1132 characters\)
  744. sed "s/^X//" >'./src/dliwritev.c' <<'END_OF_FILE'
  745. X/* $Id: dliwritev.c,v 2.1 89/10/23 15:42:10 dupuy Exp $ */
  746. X
  747. X#include <sys/param.h>            /* NOFILE */
  748. X#include <sys/socket.h>            /* sockaddr_dl (sockaddr) */
  749. X#include <sys/uio.h>            /* iovec */
  750. X
  751. X#include <net/if.h>            /* ifdevea */
  752. X#include <netinet/in.h>            /* (ether_header) (in_addr) */
  753. X#include <netinet/if_ether.h>        /* sockaddr_dl (ether_header) */
  754. X#include <netdnet/dli_var.h>        /* sockaddr_dl */
  755. X
  756. X#include <errno.h>            /* EWOULDBLOCK */
  757. X
  758. X#include "libether.h"
  759. X
  760. Xextern struct sockaddr_dl _ether_sockaddrs[NOFILE];
  761. X
  762. X#define sad (_ether_sockaddrs[fd])
  763. X
  764. X/*
  765. X * Writes a single packet, filling src and type fields.
  766. X */
  767. X
  768. Xint
  769. Xether_writev (fd, packet)
  770. Xint fd;
  771. Xether_vec *packet;
  772. X{
  773. X    struct msghdr msg;
  774. X    int result;
  775. X
  776. X    bcopy ((char *) &packet->dest,
  777. X       (char *) sad.choose_addr.dli_eaddr.dli_target, DLI_EADDRSIZE);
  778. X
  779. X    msg.msg_iov = packet->iov;
  780. X    msg.msg_iovlen = packet->iovcnt;
  781. X    msg.msg_name = (caddr_t) &sad;
  782. X    msg.msg_namelen = sizeof (sad);
  783. X    msg.msg_accrights = 0;
  784. X    msg.msg_accrightslen = 0;
  785. X
  786. X    result = sendmsg (fd, &msg, 0);
  787. X
  788. X    if (result < 0 && errno == EWOULDBLOCK)
  789. X    errno = EAGAIN;
  790. X
  791. X    return (result);
  792. X}
  793. END_OF_FILE
  794. if test 1132 -ne `wc -c <'./src/dliwritev.c'`; then
  795.     echo shar: \"'./src/dliwritev.c'\" unpacked with wrong size!
  796. fi
  797. # end of './src/dliwritev.c'
  798. fi
  799. if test -f './src/enetaddr.c' -a "${1}" != "-c" ; then 
  800.   echo shar: Will not clobber existing file \"'./src/enetaddr.c'\"
  801. else
  802. echo shar: Extracting \"'./src/enetaddr.c'\" \(1415 characters\)
  803. sed "s/^X//" >'./src/enetaddr.c' <<'END_OF_FILE'
  804. X/* $Id: enetaddr.c,v 2.0 89/10/20 19:01:58 dupuy Exp $ */
  805. X
  806. X#include <sys/types.h>            /* FD_ISSET */
  807. X#include <sys/ioctl.h>            /* ioctl */
  808. X
  809. X#include <net/enet.h>            /* endevp */
  810. X
  811. X#include "libether.h"
  812. X
  813. Xstatic fd_set addrcachevalid;
  814. X
  815. Xstatic ether_addr ifaddrs[FD_SETSIZE];
  816. X
  817. X#define ifaddr (ifaddrs[fd])
  818. X
  819. X/*
  820. X * Returns the local ethernet address for the ethernet interface on the file
  821. X * descriptor fd.  The result is stored in the structure given by address; if
  822. X * none is given, malloc is used to allocate space.  We cache results here
  823. X * because this function is called every time we send a packet.
  824. X */
  825. X
  826. Xether_addr *
  827. Xether_address (fd, address)
  828. Xint fd;
  829. Xether_addr *address;
  830. X{
  831. X    if (!FD_ISSET (fd, &addrcachevalid))
  832. X    {
  833. X    struct endevp edev;
  834. X
  835. X    if (ioctl (fd, EIOCDEVP, (char *) &edev) < 0)
  836. X    {
  837. X#ifdef DEBUG
  838. X        perror ("ether_address: ioctl EIOCDEVP");
  839. X#endif
  840. X        return (0);
  841. X    }
  842. X
  843. X    bcopy ((char *) edev.end_addr, (char *) &ifaddr, sizeof (ether_addr));
  844. X
  845. X    FD_SET (fd, &addrcachevalid);
  846. X    }
  847. X
  848. X
  849. X    if (address == 0)
  850. X    address = (ether_addr *) malloc (sizeof (ether_addr));
  851. X
  852. X    if (address != 0)
  853. X    bcopy ((char *) &ifaddr, (char *) address, sizeof (ether_addr));
  854. X
  855. X    return (address);
  856. X}
  857. X
  858. X/*
  859. X * This function is called by ether_open to invalidate the local address
  860. X * cache, since the file descriptor may be attached to a different interface.
  861. X */
  862. X
  863. Xvoid
  864. X_ether_newaddr (fd)
  865. Xint fd;
  866. X{
  867. X    FD_CLR (fd, &addrcachevalid);
  868. X}
  869. END_OF_FILE
  870. if test 1415 -ne `wc -c <'./src/enetaddr.c'`; then
  871.     echo shar: \"'./src/enetaddr.c'\" unpacked with wrong size!
  872. fi
  873. # end of './src/enetaddr.c'
  874. fi
  875. if test -f './src/enetblock.c' -a "${1}" != "-c" ; then 
  876.   echo shar: Will not clobber existing file \"'./src/enetblock.c'\"
  877. else
  878. echo shar: Extracting \"'./src/enetblock.c'\" \(980 characters\)
  879. sed "s/^X//" >'./src/enetblock.c' <<'END_OF_FILE'
  880. X/* $Id: enetblock.c,v 2.0 89/10/20 19:02:00 dupuy Exp $ */
  881. X
  882. X#include <sys/types.h>            /* eniocb (u_char) */
  883. X#include <net/enet.h>            /* eniocb */
  884. X
  885. X#define ERR (-1)
  886. X
  887. X/*
  888. X * If state is false (0), set ethernet file descriptor fd to be non-blocking,
  889. X * else set fd to be blocking. If there is an error, ether_blocking() returns
  890. X * (-1) and the appropriate value is left in errno.  Normal return status
  891. X * zero.
  892. X *
  893. X * We _ought_ to be able to use fcntl like SunOS and Ultrix, but since the enet
  894. X * special device doesn't support the FIONBIO ioctl, we can't.    This is a bug
  895. X * in the enet device driver which should be fixed.  Furthermore, this only
  896. X * prevents blocking on reads (the most common case, admittedly).  Writes to
  897. X * ethernet devices can still block waiting for queue resources.
  898. X */
  899. X
  900. Xint
  901. Xether_blocking (fd, state)
  902. Xint fd;
  903. Xint state;
  904. X{
  905. X    struct eniocb eni;
  906. X
  907. X    if (state)
  908. X    eni.en_rtout = 0;
  909. X    else
  910. X    eni.en_rtout = -1;
  911. X
  912. X    return (ioctl (fd, EIOCSETP, (char *) &eni));
  913. X}
  914. END_OF_FILE
  915. if test 980 -ne `wc -c <'./src/enetblock.c'`; then
  916.     echo shar: \"'./src/enetblock.c'\" unpacked with wrong size!
  917. fi
  918. # end of './src/enetblock.c'
  919. fi
  920. if test -f './src/enetintaddr.c' -a "${1}" != "-c" ; then 
  921.   echo shar: Will not clobber existing file \"'./src/enetintaddr.c'\"
  922. else
  923. echo shar: Extracting \"'./src/enetintaddr.c'\" \(1076 characters\)
  924. sed "s/^X//" >'./src/enetintaddr.c' <<'END_OF_FILE'
  925. X/* $Id: enetintaddr.c,v 2.0 89/10/20 19:02:02 dupuy Exp $ */
  926. X
  927. X#include <strings.h>            /* strcpy */
  928. X#include <sys/types.h>            /* (sockaddr) (u_short) */
  929. X#include <sys/socket.h>            /* IFNAMSIZ (sockaddr) */
  930. X#include <sys/file.h>            /* O_RDWR */
  931. X#include <net/if.h>            /* IFNAMSIZ */
  932. X
  933. Xextern int errno;
  934. X
  935. X#include "libether.h"
  936. X
  937. X#ifndef ENET_DEVDIR
  938. X#define ENET_DEVDIR "/dev/enet/"
  939. X#endif
  940. X
  941. X/*
  942. X * Returns the local ethernet address for an ethernet interface.  The result
  943. X * is stored in the structure given by address; if none is given, malloc is
  944. X * used to allocate space.
  945. X */
  946. X
  947. Xether_addr *
  948. Xether_intfaddr (intf, address)
  949. Xchar *intf;
  950. Xether_addr *address;
  951. X{
  952. X    char pathname[sizeof (ENET_DEVDIR) + IFNAMSIZ];
  953. X    int fd;
  954. X    int saved_errno;
  955. X
  956. X    (void) strcpy (pathname, ENET_DEVDIR);
  957. X    (void) strncat (pathname, intf, IFNAMSIZ);
  958. X
  959. X    if ((fd = open (pathname, O_RDWR)) < 0)
  960. X    {
  961. X#ifdef DEBUG
  962. X    perror (pathname);
  963. X#endif
  964. X    return (0);
  965. X    }
  966. X
  967. X    address = ether_address (fd, address);
  968. X
  969. X    saved_errno = errno;
  970. X    (void) close (fd);
  971. X    errno = saved_errno;
  972. X
  973. X    return (address);
  974. X}
  975. END_OF_FILE
  976. if test 1076 -ne `wc -c <'./src/enetintaddr.c'`; then
  977.     echo shar: \"'./src/enetintaddr.c'\" unpacked with wrong size!
  978. fi
  979. # end of './src/enetintaddr.c'
  980. fi
  981. if test -f './src/enetself.c' -a "${1}" != "-c" ; then 
  982.   echo shar: Will not clobber existing file \"'./src/enetself.c'\"
  983. else
  984. echo shar: Extracting \"'./src/enetself.c'\" \(601 characters\)
  985. sed "s/^X//" >'./src/enetself.c' <<'END_OF_FILE'
  986. X/* $Id: enetself.c,v 2.0 89/10/20 19:02:05 dupuy Exp $ */
  987. X
  988. X/*
  989. X * Most, but not all, VAX interfaces, loopback packets.     The enetfilter
  990. X * drivers for the ec (3com) interface loops back packets in software, except
  991. X * for multicast packets.  Since the enetfilter currently has no way to
  992. X * receive multicast packets, that makes little difference.
  993. X */
  994. X
  995. X/* ARGSUSED */
  996. X
  997. Xint
  998. Xether_send_self (fd)
  999. Xint fd;
  1000. X{
  1001. X    return (1);
  1002. X}
  1003. X
  1004. X/* ARGSUSED */
  1005. X
  1006. Xint
  1007. Xether_mcast_self (fd)
  1008. Xint fd;
  1009. X{
  1010. X    return (0);                /* can't receive multicast packets */
  1011. X}
  1012. X
  1013. X/* ARGSUSED */
  1014. X
  1015. Xint
  1016. Xether_bcast_self (fd)
  1017. Xint fd;
  1018. X{
  1019. X    return (1);
  1020. X}
  1021. END_OF_FILE
  1022. if test 601 -ne `wc -c <'./src/enetself.c'`; then
  1023.     echo shar: \"'./src/enetself.c'\" unpacked with wrong size!
  1024. fi
  1025. # end of './src/enetself.c'
  1026. fi
  1027. if test -f './src/enetwrite.c' -a "${1}" != "-c" ; then 
  1028.   echo shar: Will not clobber existing file \"'./src/enetwrite.c'\"
  1029. else
  1030. echo shar: Extracting \"'./src/enetwrite.c'\" \(1012 characters\)
  1031. sed "s/^X//" >'./src/enetwrite.c' <<'END_OF_FILE'
  1032. X/* $Id: enetwrite.c,v 2.1 89/10/24 17:53:05 dupuy Exp $ */
  1033. X
  1034. X#include <sys/types.h>            /* iovec (caddr_t) */
  1035. X#include <sys/uio.h>            /* iovec */
  1036. X
  1037. X#include "libether.h"
  1038. X
  1039. Xextern unsigned _ether_types[FD_SETSIZE];
  1040. X
  1041. X#define ether_type (_ether_types[fd])
  1042. X
  1043. X#define HEADER    0
  1044. X#define DATA    1
  1045. X#define MAXIOV    2
  1046. X
  1047. X/*
  1048. X * Writes a single packet, filling src and type fields.     We have to fill in
  1049. X * the src field in user space, since the enetfilter doesn't do it for us, and
  1050. X * at least some VAX interface devices don't do it either.
  1051. X */
  1052. X
  1053. Xint
  1054. Xether_write (fd, packet)
  1055. Xint fd;
  1056. Xether_packet *packet;
  1057. X{
  1058. X    struct iovec iov[MAXIOV];
  1059. X
  1060. X    iov[HEADER].iov_len = ETHER_PKT;
  1061. X    iov[HEADER].iov_base = (char *) packet;
  1062. X
  1063. X    iov[DATA].iov_len = packet->pktlen;
  1064. X    iov[DATA].iov_base = packet->pktbuf;
  1065. X
  1066. X    if (ether_type != ETHER_ALLTYPES)
  1067. X    {
  1068. X    packet->type[0] = (ether_type >> 8) & 0xff;
  1069. X    packet->type[1] = ether_type & 0xff;
  1070. X    }
  1071. X
  1072. X    (void) ether_address (fd, (ether_addr *) &packet->src);
  1073. X
  1074. X    return (writev (fd, iov, MAXIOV));
  1075. X}
  1076. END_OF_FILE
  1077. if test 1012 -ne `wc -c <'./src/enetwrite.c'`; then
  1078.     echo shar: \"'./src/enetwrite.c'\" unpacked with wrong size!
  1079. fi
  1080. # end of './src/enetwrite.c'
  1081. fi
  1082. if test -f './src/enetwritev.c' -a "${1}" != "-c" ; then 
  1083.   echo shar: Will not clobber existing file \"'./src/enetwritev.c'\"
  1084. else
  1085. echo shar: Extracting \"'./src/enetwritev.c'\" \(1313 characters\)
  1086. sed "s/^X//" >'./src/enetwritev.c' <<'END_OF_FILE'
  1087. X/* $Id: enetwritev.c,v 2.2 89/10/24 17:53:10 dupuy Exp $ */
  1088. X
  1089. X#include <sys/types.h>            /* iovec (caddr_t) */
  1090. X#include <sys/uio.h>            /* iovec */
  1091. X
  1092. X#include "libether.h"
  1093. X
  1094. X#ifdef __GNUC__
  1095. X#define alloca __builtin_alloca
  1096. X#else
  1097. X#ifdef lint
  1098. Xextern double *dalloca ();
  1099. X#define alloca dalloca
  1100. X#else
  1101. X#ifdef sparc
  1102. X#include <alloca.h>
  1103. X#endif
  1104. Xextern char *alloca ();
  1105. X#endif
  1106. X#endif
  1107. X
  1108. Xextern unsigned _ether_types[FD_SETSIZE];
  1109. X
  1110. X#define ether_type (_ether_types[fd])
  1111. X
  1112. X#define HEADER    0
  1113. X#define USER    1
  1114. X
  1115. X/*
  1116. X * Writes a single packet, filling src and type fields.     We have to fill in
  1117. X * the src field in user space, since the enetfilter doesn't do it for us, and
  1118. X * at least some VAX interface devices don't do it either.
  1119. X */
  1120. X
  1121. Xint
  1122. Xether_writev (fd, packet)
  1123. Xint fd;
  1124. Xether_vec *packet;
  1125. X{
  1126. X    int count = 1 + packet->iovcnt;
  1127. X    struct iovec *iov =
  1128. X    (struct iovec *) alloca (sizeof (struct iovec) * count);
  1129. X
  1130. X    iov[HEADER].iov_len = ETHER_PKT;
  1131. X    iov[HEADER].iov_base = (char *) packet;
  1132. X
  1133. X    (void) bcopy ((char *) packet->iov, (char *) &iov[USER],
  1134. X          (int) packet->iovcnt * sizeof (struct iovec));
  1135. X
  1136. X    if (ether_type != ETHER_ALLTYPES)
  1137. X    {
  1138. X    packet->type[0] = (ether_type >> 8) & 0xff;
  1139. X    packet->type[1] = ether_type & 0xff;
  1140. X    }
  1141. X
  1142. X    (void) ether_address (fd, (ether_addr *) &packet->src);
  1143. X
  1144. X    return (writev (fd, iov, count));
  1145. X}
  1146. END_OF_FILE
  1147. if test 1313 -ne `wc -c <'./src/enetwritev.c'`; then
  1148.     echo shar: \"'./src/enetwritev.c'\" unpacked with wrong size!
  1149. fi
  1150. # end of './src/enetwritev.c'
  1151. fi
  1152. if test -f './src/ethera2e.c' -a "${1}" != "-c" ; then 
  1153.   echo shar: Will not clobber existing file \"'./src/ethera2e.c'\"
  1154. else
  1155. echo shar: Extracting \"'./src/ethera2e.c'\" \(995 characters\)
  1156. sed "s/^X//" >'./src/ethera2e.c' <<'END_OF_FILE'
  1157. X/* $Id: ethera2e.c,v 2.1 89/10/23 15:42:22 dupuy Exp $ */
  1158. X
  1159. X#include <stdio.h>            /* sscanf */
  1160. X
  1161. X#include "libether.h"
  1162. X
  1163. X#define EBYTES 6
  1164. X
  1165. Xether_addr *
  1166. Xether_a2e (estring, addr)
  1167. Xchar *estring;
  1168. Xether_addr *addr;
  1169. X{
  1170. X    unsigned bytes[EBYTES];
  1171. X    int allocated = 0;
  1172. X    int i;
  1173. X
  1174. X    if (addr == NULL)
  1175. X    {
  1176. X    addr = (ether_addr *) malloc (sizeof (ether_addr));
  1177. X    allocated++;
  1178. X    }
  1179. X
  1180. X    if (addr != NULL)
  1181. X    if (sscanf (estring, " %2x:%2x:%2x:%2x:%2x:%2x", &bytes[0], &bytes[1],
  1182. X            &bytes[2], &bytes[3], &bytes[4], &bytes[5])
  1183. X        == EBYTES ||
  1184. X        sscanf (estring, " %2x-%2x-%2x-%2x-%2x-%2x", &bytes[0], &bytes[1],
  1185. X            &bytes[2], &bytes[3], &bytes[4], &bytes[5])
  1186. X        == EBYTES)
  1187. X    {
  1188. X        for (i = 0; i < EBYTES; i++)
  1189. X        addr->bytes[i] = bytes[i];
  1190. X    }
  1191. X    else
  1192. X    {
  1193. X        if (allocated)
  1194. X        (void) free ((char *) addr);
  1195. X        addr = NULL;
  1196. X    }
  1197. X
  1198. X    return (addr);
  1199. X}
  1200. X
  1201. X#ifndef ETHERDB
  1202. X
  1203. Xether_addr *
  1204. Xether_aton (estring)
  1205. Xchar *estring;
  1206. X{
  1207. X    static ether_addr addr;
  1208. X
  1209. X    return (ether_a2e (estring, &addr));
  1210. X}
  1211. X
  1212. X#endif
  1213. END_OF_FILE
  1214. if test 995 -ne `wc -c <'./src/ethera2e.c'`; then
  1215.     echo shar: \"'./src/ethera2e.c'\" unpacked with wrong size!
  1216. fi
  1217. # end of './src/ethera2e.c'
  1218. fi
  1219. if test -f './src/etheraddr.c' -a "${1}" != "-c" ; then 
  1220.   echo shar: Will not clobber existing file \"'./src/etheraddr.c'\"
  1221. else
  1222. echo shar: Extracting \"'./src/etheraddr.c'\" \(755 characters\)
  1223. sed "s/^X//" >'./src/etheraddr.c' <<'END_OF_FILE'
  1224. X/* $Id: etheraddr.c,v 2.1 89/10/23 15:44:44 dupuy Exp $ */
  1225. X
  1226. X/*
  1227. X * Static initialization of ethernet broadcast address.     We do it in a separate
  1228. X * file so that it can be compiled with -R (read-only), but more importatntly,
  1229. X * so that we can get around the restriction on initializing unions if needed.
  1230. X */
  1231. X
  1232. X#ifdef __STDC__
  1233. X
  1234. X#include "ether.h"
  1235. X
  1236. Xether_addr ether_bcast_addr = {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }};
  1237. X
  1238. X#else
  1239. X
  1240. X#ifdef lint
  1241. X
  1242. X#include "ether.h"
  1243. X
  1244. Xether_addr ether_bcast_addr;        /* a little white lie */
  1245. X
  1246. X#else
  1247. X
  1248. X#define __ETHER_BCAST_ADDR__        /* avoid conflict with ether.h */
  1249. X
  1250. X#include "ether.h"
  1251. X
  1252. Xstruct ether_addr
  1253. X{
  1254. X    unsigned short shorts[3];        /* must have short alignment */
  1255. X}
  1256. Xether_bcast_addr =  {{ 0xffff, 0xffff, 0xffff }};
  1257. X
  1258. X#endif
  1259. X
  1260. X#endif
  1261. END_OF_FILE
  1262. if test 755 -ne `wc -c <'./src/etheraddr.c'`; then
  1263.     echo shar: \"'./src/etheraddr.c'\" unpacked with wrong size!
  1264. fi
  1265. # end of './src/etheraddr.c'
  1266. fi
  1267. if test -f './src/etherblock.c' -a "${1}" != "-c" ; then 
  1268.   echo shar: Will not clobber existing file \"'./src/etherblock.c'\"
  1269. else
  1270. echo shar: Extracting \"'./src/etherblock.c'\" \(890 characters\)
  1271. sed "s/^X//" >'./src/etherblock.c' <<'END_OF_FILE'
  1272. X/* $Id: etherblock.c,v 2.1 89/10/23 15:42:26 dupuy Exp $ */
  1273. X
  1274. X#include <sys/file.h>            /* FNBIO/FNDELAY */
  1275. X
  1276. X#ifdef __STDC__
  1277. Xextern int fcntl (int f, int c, int a);
  1278. X#else
  1279. Xextern int fcntl ();
  1280. X#endif
  1281. X
  1282. X#ifdef FNBIO
  1283. X#define FNOBLOCK FNBIO
  1284. X#else
  1285. X#define FNOBLOCK FNDELAY
  1286. X#endif
  1287. X
  1288. X#define ERR (-1)
  1289. X
  1290. X/*
  1291. X * If state is false (0), set ethernet file descriptor fd to be non-blocking,
  1292. X * else set fd to be blocking. If there is an error, ether_blocking() returns
  1293. X * (-1) and the appropriate value is left in errno.  Normal return status
  1294. X * zero.
  1295. X */
  1296. X
  1297. Xint
  1298. Xether_blocking (fd, state)
  1299. Xint fd;
  1300. Xint state;
  1301. X{
  1302. X    int flags;
  1303. X
  1304. X    if ((flags = fcntl (fd, F_GETFL, -1)) < 0)
  1305. X    return (ERR);
  1306. X
  1307. X    if (state)
  1308. X    if (flags & FNOBLOCK)
  1309. X        state = fcntl (fd, F_SETFL, flags & ~FNOBLOCK);
  1310. X    else
  1311. X        state = 0;
  1312. X    else if ((flags & FNOBLOCK) == 0)
  1313. X    state = fcntl (fd, F_SETFL, flags | FNOBLOCK);
  1314. X
  1315. X    return (state);
  1316. X}
  1317. END_OF_FILE
  1318. if test 890 -ne `wc -c <'./src/etherblock.c'`; then
  1319.     echo shar: \"'./src/etherblock.c'\" unpacked with wrong size!
  1320. fi
  1321. # end of './src/etherblock.c'
  1322. fi
  1323. if test -f './src/ethere2a.c' -a "${1}" != "-c" ; then 
  1324.   echo shar: Will not clobber existing file \"'./src/ethere2a.c'\"
  1325. else
  1326. echo shar: Extracting \"'./src/ethere2a.c'\" \(630 characters\)
  1327. sed "s/^X//" >'./src/ethere2a.c' <<'END_OF_FILE'
  1328. X/* $Id: ethere2a.c,v 2.1 89/10/23 15:42:28 dupuy Exp $ */
  1329. X
  1330. X#include <stdio.h>
  1331. X
  1332. X#include "libether.h"
  1333. X
  1334. Xchar *
  1335. Xether_e2a (addr, estring)
  1336. Xether_addr *addr;
  1337. Xchar *estring;
  1338. X{
  1339. X#ifdef lint
  1340. X    char *sprintf ();
  1341. X#endif
  1342. X    if (estring == NULL)
  1343. X    estring = (char *) malloc (ETHERSTRLEN);
  1344. X
  1345. X    if (estring != NULL)
  1346. X    (void) sprintf (estring, "%x:%x:%x:%x:%x:%x",
  1347. X            addr->bytes[0], addr->bytes[1], addr->bytes[2],
  1348. X            addr->bytes[3], addr->bytes[4], addr->bytes[5]);
  1349. X    return (estring);
  1350. X}
  1351. X
  1352. X#ifndef ETHERDB
  1353. X
  1354. Xchar *
  1355. Xether_ntoa (addr)
  1356. Xether_addr *addr;
  1357. X{
  1358. X    static char estring[ETHERSTRLEN];
  1359. X
  1360. X    return (ether_e2a (addr, estring));
  1361. X}
  1362. X
  1363. X#endif
  1364. END_OF_FILE
  1365. if test 630 -ne `wc -c <'./src/ethere2a.c'`; then
  1366.     echo shar: \"'./src/ethere2a.c'\" unpacked with wrong size!
  1367. fi
  1368. # end of './src/ethere2a.c'
  1369. fi
  1370. if test -f './src/etherlocal.c' -a "${1}" != "-c" ; then 
  1371.   echo shar: Will not clobber existing file \"'./src/etherlocal.c'\"
  1372. else
  1373. echo shar: Extracting \"'./src/etherlocal.c'\" \(1143 characters\)
  1374. sed "s/^X//" >'./src/etherlocal.c' <<'END_OF_FILE'
  1375. X/* $Id: etherlocal.c,v 2.1 89/10/23 15:42:38 dupuy Exp $ */
  1376. X
  1377. X#include <sys/types.h>            /* (u_char) */
  1378. X#include <sys/socket.h>            /* sockaddr_in (sockaddr) */
  1379. X#include <net/if.h>            /* ifconf */
  1380. X#include <netinet/in.h>            /* sockaddr_in */
  1381. X#include <errno.h>
  1382. X
  1383. Xextern int errno;
  1384. X
  1385. X#include "libether.h"
  1386. X
  1387. Xextern short _ether_ifindex[MAXNUMIF];    /* from ether_interfaces() */
  1388. Xextern struct ifconf _ether_ifconf;    /* from ether_interfaces() */
  1389. X
  1390. X
  1391. Xint
  1392. X_ether_localif (addr, ipaddr)
  1393. Xether_addr *addr;
  1394. Xstruct in_addr *ipaddr;
  1395. X{
  1396. X    char **intfs;
  1397. X    int i;
  1398. X
  1399. X    if ((intfs = ether_interfaces ()) == 0)
  1400. X    return (0);
  1401. X
  1402. X    for (i = 0; *intfs; intfs++, i++)
  1403. X    {
  1404. X    ether_addr eaddr;
  1405. X
  1406. X    if (_ether_ifindex[i] < 0)
  1407. X        continue;            /* not an AF_INET interface */
  1408. X
  1409. X    if (ether_intfaddr (*intfs, &eaddr) == 0)
  1410. X        return (0);
  1411. X
  1412. X    if (ether_cmp (addr, &eaddr) == 0)
  1413. X    {
  1414. X        struct sockaddr_in *inaddr;
  1415. X
  1416. X        inaddr = (struct sockaddr_in *)
  1417. X        &_ether_ifconf.ifc_req[_ether_ifindex[i]].ifr_addr;
  1418. X
  1419. X        (void) bcopy ((char *) &inaddr->sin_addr, (char *) ipaddr,
  1420. X              sizeof (*ipaddr));
  1421. X        return (1);
  1422. X    }
  1423. X    }
  1424. X
  1425. X    return (0);                /* doesn't match any local interface */
  1426. X}
  1427. END_OF_FILE
  1428. if test 1143 -ne `wc -c <'./src/etherlocal.c'`; then
  1429.     echo shar: \"'./src/etherlocal.c'\" unpacked with wrong size!
  1430. fi
  1431. # end of './src/etherlocal.c'
  1432. fi
  1433. if test -f './src/etherread.c' -a "${1}" != "-c" ; then 
  1434.   echo shar: Will not clobber existing file \"'./src/etherread.c'\"
  1435. else
  1436. echo shar: Extracting \"'./src/etherread.c'\" \(1860 characters\)
  1437. sed "s/^X//" >'./src/etherread.c' <<'END_OF_FILE'
  1438. X/* $Id: etherread.c,v 2.1 89/10/23 15:42:40 dupuy Exp $ */
  1439. X
  1440. X#include <sys/types.h>            /* iovec (caddr_t) */
  1441. X#include <sys/uio.h>            /* iovec */
  1442. X
  1443. X#include <errno.h>            /* EWOULDBLOCK/EMSGSIZE */
  1444. X
  1445. Xextern int errno;
  1446. X
  1447. X#include "libether.h"
  1448. X
  1449. X#define HEADER    0
  1450. X#define DATA    1
  1451. X#define WASTE    2
  1452. X#define MAXIOV    3
  1453. X
  1454. X/*
  1455. X * Reads and returns a single packet, filling in all fields.  If pktbuf is
  1456. X * NULL, a buffer is allocated for it.    If pktbuf is not NULL, the function
  1457. X * assumes that pktbuf is large enough to hold pktlen bytes.  Reads on the
  1458. X * ethernet packet filter device always return one packet.  Streams must be in
  1459. X * RMSGD mode for reads to return one packet at a time
  1460. X */
  1461. X
  1462. Xint
  1463. Xether_read (fd, packet)
  1464. Xint fd;
  1465. Xether_packet *packet;
  1466. X{
  1467. X    char waste[ETHER_MAX];
  1468. X    struct iovec iov[MAXIOV];
  1469. X    int count;
  1470. X
  1471. X    iov[HEADER].iov_len = ETHER_PKT;
  1472. X    iov[HEADER].iov_base = (char *) packet;
  1473. X
  1474. X    if (packet->pktbuf)
  1475. X    {
  1476. X    iov[DATA].iov_len = packet->pktlen;
  1477. X    iov[DATA].iov_base = packet->pktbuf;
  1478. X
  1479. X    iov[WASTE].iov_len = sizeof (waste);
  1480. X    iov[WASTE].iov_base = waste;
  1481. X
  1482. X    count = 3;            /* use waste to get all of packet */
  1483. X    }
  1484. X    else
  1485. X    {
  1486. X    iov[DATA].iov_len = packet->pktlen = ETHER_MAX;
  1487. X    if ((iov[DATA].iov_base = (char *) malloc ((unsigned) ETHER_MAX)) == 0)
  1488. X        return (-1);
  1489. X    packet->pktbuf = iov[DATA].iov_base;
  1490. X
  1491. X    count = 2;            /* no need to use waste */
  1492. X    }
  1493. X
  1494. X    if ((count = readv (fd, iov, count)) <= 0)
  1495. X    {
  1496. X#ifndef EBADMSG                /* a stream will return EAGAIN */
  1497. X    if (count == 0 || errno == EWOULDBLOCK)
  1498. X        errno = EAGAIN;
  1499. X#endif
  1500. X    return (-1);
  1501. X    }
  1502. X
  1503. X    if ((count -= ETHER_PKT) < 0)
  1504. X    {                    /* enet returns EOF (0) */
  1505. X#ifdef EBADMSG
  1506. X    errno = EBADMSG;        /* XXX readv() can also return this */
  1507. X#else
  1508. X    errno = EMSGSIZE;        /* XXX message isn't really too long */
  1509. X#endif
  1510. X    }
  1511. X    else if (packet->pktlen > count)
  1512. X    packet->pktlen = count;
  1513. X
  1514. X    return (count);
  1515. X}
  1516. END_OF_FILE
  1517. if test 1860 -ne `wc -c <'./src/etherread.c'`; then
  1518.     echo shar: \"'./src/etherread.c'\" unpacked with wrong size!
  1519. fi
  1520. # end of './src/etherread.c'
  1521. fi
  1522. if test -f './src/etherreadv.c' -a "${1}" != "-c" ; then 
  1523.   echo shar: Will not clobber existing file \"'./src/etherreadv.c'\"
  1524. else
  1525. echo shar: Extracting \"'./src/etherreadv.c'\" \(1628 characters\)
  1526. sed "s/^X//" >'./src/etherreadv.c' <<'END_OF_FILE'
  1527. X/* $Id: etherreadv.c,v 2.1 89/10/23 15:42:42 dupuy Exp $ */
  1528. X
  1529. X#include <sys/types.h>            /* iovec (caddr_t) */
  1530. X#include <sys/uio.h>            /* iovec */
  1531. X
  1532. X#include <errno.h>            /* EWOULDBLOCK/EMSGSIZE */
  1533. X
  1534. Xextern int errno;
  1535. X
  1536. X#include "libether.h"
  1537. X
  1538. X#ifdef __GNUC__
  1539. X#define alloca __builtin_alloca
  1540. X#else
  1541. X#ifdef lint
  1542. Xextern double *dalloca ();
  1543. X#define alloca dalloca
  1544. X#else
  1545. X#ifdef sparc
  1546. X#include <alloca.h>
  1547. X#endif
  1548. Xextern char *alloca ();
  1549. X#endif
  1550. X#endif
  1551. X
  1552. X#define HEADER    0
  1553. X#define USER    1
  1554. X#define WASTE    (count - 1)
  1555. X
  1556. X/*
  1557. X * Reads and returns a single packet, filling in all fields.  Reads on the
  1558. X * ethernet packet filter device always return one packet.  Streams must be in
  1559. X * RMSGD mode for reads to return one packet at a time
  1560. X */
  1561. X
  1562. Xint
  1563. Xether_readv (fd, packet)
  1564. Xint fd;
  1565. Xether_vec *packet;
  1566. X{
  1567. X    char waste[ETHER_MAX];
  1568. X    int count = 2 + packet->iovcnt;
  1569. X    struct iovec *iov =
  1570. X    (struct iovec *) alloca (sizeof (struct iovec) * count);
  1571. X
  1572. X    iov[HEADER].iov_len = ETHER_PKT;
  1573. X    iov[HEADER].iov_base = (char *) packet;
  1574. X
  1575. X    (void) bcopy ((char *) packet->iov, (char *) &iov[USER],
  1576. X          (int) packet->iovcnt * sizeof (struct iovec));
  1577. X
  1578. X    iov[WASTE].iov_len = sizeof (waste);
  1579. X    iov[WASTE].iov_base = waste;
  1580. X
  1581. X    if ((count = readv (fd, iov, count)) <= 0)
  1582. X    {                    /* enet returns EOF (0) */
  1583. X#ifndef EBADMSG                /* a stream will return EAGAIN */
  1584. X    if (count == 0 || errno == EWOULDBLOCK)
  1585. X        errno = EAGAIN;
  1586. X#endif
  1587. X    return (-1);
  1588. X    }
  1589. X
  1590. X    if ((count -= ETHER_PKT) < 0)
  1591. X    {
  1592. X#ifdef EBADMSG
  1593. X    errno = EBADMSG;        /* XXX readv() can also return this */
  1594. X#else
  1595. X    errno = EMSGSIZE;        /* XXX message isn't really too long */
  1596. X#endif
  1597. X    }
  1598. X
  1599. X    return (count);
  1600. X}
  1601. END_OF_FILE
  1602. if test 1628 -ne `wc -c <'./src/etherreadv.c'`; then
  1603.     echo shar: \"'./src/etherreadv.c'\" unpacked with wrong size!
  1604. fi
  1605. # end of './src/etherreadv.c'
  1606. fi
  1607. if test -f './src/libether.h' -a "${1}" != "-c" ; then 
  1608.   echo shar: Will not clobber existing file \"'./src/libether.h'\"
  1609. else
  1610. echo shar: Extracting \"'./src/libether.h'\" \(1312 characters\)
  1611. sed "s/^X//" >'./src/libether.h' <<'END_OF_FILE'
  1612. X/* $Id: libether.h,v 2.1 89/10/23 15:42:44 dupuy Exp $ */
  1613. X
  1614. X/* Internal definitions for ethernet access library */
  1615. X
  1616. X#include "ether.h"            /* get interface definitions */
  1617. X
  1618. X#define MAXNUMIF 16            /* maximum number of interfaces */
  1619. X
  1620. X#define ETHER_BUFFERS    5        /* for socket based NIT interface */
  1621. X#define ETHER_BUFSIZ \
  1622. X (ETHER_BUFFERS * (ETHER_PKT + ETHER_MAX + (2 * sizeof (struct nit_hdr))))
  1623. X
  1624. X#define ALIGNSIZE    (sizeof (int))
  1625. X#define pad(x)        ((ALIGNSIZE - ((unsigned)(x)) % ALIGNSIZE) % ALIGNSIZE)
  1626. X
  1627. X#define address_check(dest) \
  1628. X (ETHER_MCAST (dest) \
  1629. X  && bcmp ((char *)(dest), (char *) ðer_bcast_addr, sizeof (ether_addr)) \
  1630. X  && bcmp ((char *)(dest), (char *) &_ether_multi_addrs[fd], \
  1631. X       sizeof (ether_addr)))
  1632. X
  1633. X#ifdef __STDC__
  1634. X
  1635. Xextern char *malloc (unsigned size);
  1636. X
  1637. Xextern int _ether_arpscan (ether_addr *addr, struct in_addr *ipaddr);
  1638. Xextern int _ether_localif (ether_addr *addr, struct in_addr *ipaddr);
  1639. X#ifdef RARP
  1640. Xextern int _ether_rarpprobe (ether_addr *addr, struct in_addr *ipaddr);
  1641. X#endif
  1642. X
  1643. X#else
  1644. X
  1645. X#ifdef lint
  1646. X
  1647. X#ifndef htons
  1648. X
  1649. Xextern unsigned short htons ();
  1650. X
  1651. X#endif
  1652. X
  1653. X#ifdef ultrix
  1654. X
  1655. Xextern void bzero ();
  1656. Xextern void bcopy ();
  1657. Xextern void free ();
  1658. Xextern void perror ();
  1659. X
  1660. X#endif
  1661. X
  1662. Xextern double *dalloc ();
  1663. X#define malloc dalloc
  1664. X
  1665. X#else
  1666. X
  1667. Xextern char *malloc ();
  1668. X
  1669. X#endif /* lint */
  1670. X
  1671. X#endif /* __STDC__ */
  1672. END_OF_FILE
  1673. if test 1312 -ne `wc -c <'./src/libether.h'`; then
  1674.     echo shar: \"'./src/libether.h'\" unpacked with wrong size!
  1675. fi
  1676. # end of './src/libether.h'
  1677. fi
  1678. if test -f './src/nit3intaddr.c' -a "${1}" != "-c" ; then 
  1679.   echo shar: Will not clobber existing file \"'./src/nit3intaddr.c'\"
  1680. else
  1681. echo shar: Extracting \"'./src/nit3intaddr.c'\" \(1250 characters\)
  1682. sed "s/^X//" >'./src/nit3intaddr.c' <<'END_OF_FILE'
  1683. X/* $Id: nit3intaddr.c,v 2.1 89/10/23 15:42:47 dupuy Exp $ */
  1684. X
  1685. X#include <sys/types.h>            /* AF_NIT (u_short) */
  1686. X#include <sys/socket.h>            /* AF_NIT */
  1687. X
  1688. Xextern int errno;
  1689. X
  1690. X#include "libether.h"
  1691. X
  1692. Xether_addr _ether_localaddr;        /* shared with ether_address() */
  1693. Xint _ether_haveaddress;            /* shared with ether_address() */
  1694. X
  1695. X/*
  1696. X * Returns the local ethernet address for an ethernet interface.  The result
  1697. X * is stored in the structure given by address; if none is given, malloc is
  1698. X * used to allocate space.  Sun systems have the "feature" that all ethernet
  1699. X * interfaces are set to the same address (taken from the ID PROM).  So we can
  1700. X * get the answer once, and use it forever.
  1701. X */
  1702. X
  1703. X/* ARGSUSED */
  1704. X
  1705. Xether_addr *
  1706. Xether_intfaddr (intf, address)
  1707. Xchar *intf;
  1708. Xether_addr *address;
  1709. X{
  1710. X    if (!_ether_haveaddress)
  1711. X    {
  1712. X    int fd;
  1713. X    int saved_errno;
  1714. X
  1715. X    if ((fd = socket (AF_NIT, SOCK_RAW, 0)) < 0)
  1716. X    {
  1717. X#ifdef DEBUG
  1718. X        perror ("ether_open: socket");
  1719. X#endif
  1720. X        return (0);
  1721. X    }
  1722. X
  1723. X    address = ether_address (fd, address);
  1724. X
  1725. X    saved_errno = errno;
  1726. X    (void) close (fd);
  1727. X    errno = saved_errno;
  1728. X
  1729. X    return (address);
  1730. X    }
  1731. X
  1732. X    if (address == 0)
  1733. X    address = (ether_addr *) malloc (sizeof (ether_addr));
  1734. X
  1735. X    if (address != 0)
  1736. X    *address = _ether_localaddr;
  1737. X
  1738. X    return (address);
  1739. X}
  1740. END_OF_FILE
  1741. if test 1250 -ne `wc -c <'./src/nit3intaddr.c'`; then
  1742.     echo shar: \"'./src/nit3intaddr.c'\" unpacked with wrong size!
  1743. fi
  1744. # end of './src/nit3intaddr.c'
  1745. fi
  1746. if test -f './src/nit3read.c' -a "${1}" != "-c" ; then 
  1747.   echo shar: Will not clobber existing file \"'./src/nit3read.c'\"
  1748. else
  1749. echo shar: Extracting \"'./src/nit3read.c'\" \(1151 characters\)
  1750. sed "s/^X//" >'./src/nit3read.c' <<'END_OF_FILE'
  1751. X/* $Id: nit3read.c,v 2.1 89/10/23 15:42:53 dupuy Exp $ */
  1752. X
  1753. X#include "libether.h"
  1754. X
  1755. X/*
  1756. X * Reads and returns a single packet, filling in all fields.  If pktbuf is
  1757. X * NULL, a buffer is allocated for it.    If pktbuf is not NULL, the function
  1758. X * assumes that pktbuf is large enough to hold pktlen bytes.  Since read() may
  1759. X * return several packets at a time, we have to buffer them as well.  Since
  1760. X * socket based nit doesn't handle multicast addresses, we have to check them
  1761. X * at the user level.
  1762. X *
  1763. X * NOTE - the buffering code is not re-entrant, although different fd's will
  1764. X * not conflict.
  1765. X */
  1766. X
  1767. Xint
  1768. Xether_read (fd, packet)
  1769. Xint fd;
  1770. Xether_packet *packet;
  1771. X{
  1772. X    char *pbuf;
  1773. X    int bytes;
  1774. X
  1775. X    if ((bytes = _ether_next_packet (fd, &pbuf)) < 0)
  1776. X    return (-1);
  1777. X
  1778. X    bcopy (pbuf, (char *) packet, ETHER_PKT);
  1779. X    pbuf += ETHER_PKT;
  1780. X
  1781. X    if (packet->pktbuf == 0)
  1782. X    {
  1783. X    packet->pktlen = bytes;
  1784. X    if ((packet->pktbuf = (char *) malloc ((unsigned) bytes)) == 0)
  1785. X        return (-1);
  1786. X    }
  1787. X
  1788. X    bcopy (pbuf, packet->pktbuf,
  1789. X       (int) ((packet->pktlen > bytes) ? bytes : packet->pktlen));
  1790. X
  1791. X    if (packet->pktlen > bytes)
  1792. X    packet->pktlen = bytes;
  1793. X
  1794. X    return (bytes);
  1795. X}
  1796. END_OF_FILE
  1797. if test 1151 -ne `wc -c <'./src/nit3read.c'`; then
  1798.     echo shar: \"'./src/nit3read.c'\" unpacked with wrong size!
  1799. fi
  1800. # end of './src/nit3read.c'
  1801. fi
  1802. if test -f './src/nit3readv.c' -a "${1}" != "-c" ; then 
  1803.   echo shar: Will not clobber existing file \"'./src/nit3readv.c'\"
  1804. else
  1805. echo shar: Extracting \"'./src/nit3readv.c'\" \(1251 characters\)
  1806. sed "s/^X//" >'./src/nit3readv.c' <<'END_OF_FILE'
  1807. X/* $Id: nit3readv.c,v 2.0 89/10/20 19:02:38 dupuy Exp $ */
  1808. X
  1809. X#include <sys/types.h>            /* iovec (caddr_t) */
  1810. X#include <sys/uio.h>            /* iovec */
  1811. X
  1812. X#include "libether.h"
  1813. X
  1814. X/*
  1815. X * Reads and returns a single packet, filling in all fields.  Since read() may
  1816. X * return several packets at a time, we have to buffer them as well.  Since
  1817. X * socket based nit doesn't handle multicast addresses, we have to check them
  1818. X * at the user level.
  1819. X *
  1820. X * NOTE - the buffering code is not re-entrant, although different fd's will
  1821. X * not conflict.
  1822. X */
  1823. X
  1824. Xint
  1825. Xether_readv (fd, packet)
  1826. Xint fd;
  1827. Xether_vec *packet;
  1828. X{
  1829. X    char *pbuf;
  1830. X    int index = 0;
  1831. X    int count;
  1832. X    int bytes;
  1833. X
  1834. X    if ((bytes = _ether_next_packet (fd, &pbuf)) < 0)
  1835. X    return (-1);
  1836. X
  1837. X    bcopy (pbuf, (char *) packet, ETHER_PKT);
  1838. X    pbuf += ETHER_PKT;
  1839. X
  1840. X    for (count = 0; count < packet->iovcnt && index < bytes; count++)
  1841. X    if (packet->iov[count].iov_len)
  1842. X    {
  1843. X        if (bytes - index < packet->iov[count].iov_len)
  1844. X        {
  1845. X        bcopy (&pbuf[index], (char *) packet->iov[count].iov_base,
  1846. X               bytes - index);
  1847. X        break;
  1848. X        }
  1849. X        else
  1850. X        {
  1851. X        bcopy (&pbuf[index], (char *) packet->iov[count].iov_base,
  1852. X               (int) packet->iov[count].iov_len);
  1853. X        index += packet->iov[count].iov_len;
  1854. X        }
  1855. X    }
  1856. X
  1857. X    return (bytes);
  1858. X}
  1859. END_OF_FILE
  1860. if test 1251 -ne `wc -c <'./src/nit3readv.c'`; then
  1861.     echo shar: \"'./src/nit3readv.c'\" unpacked with wrong size!
  1862. fi
  1863. # end of './src/nit3readv.c'
  1864. fi
  1865. if test -f './src/nit3self.c' -a "${1}" != "-c" ; then 
  1866.   echo shar: Will not clobber existing file \"'./src/nit3self.c'\"
  1867. else
  1868. echo shar: Extracting \"'./src/nit3self.c'\" \(396 characters\)
  1869. sed "s/^X//" >'./src/nit3self.c' <<'END_OF_FILE'
  1870. X/* $Id: nit3self.c,v 2.0 89/10/20 19:02:40 dupuy Exp $ */
  1871. X
  1872. X/*
  1873. X * No standard sun ethernet interface loops back packets. The socket-based Sun
  1874. X * NIT interface doesn't do it either.
  1875. X */
  1876. X
  1877. X/* ARGSUSED */
  1878. X
  1879. Xint
  1880. Xether_send_self (fd)
  1881. Xint fd;
  1882. X{
  1883. X    return (0);
  1884. X}
  1885. X
  1886. X/* ARGSUSED */
  1887. X
  1888. Xint
  1889. Xether_mcast_self (fd)
  1890. Xint fd;
  1891. X{
  1892. X    return (0);
  1893. X}
  1894. X
  1895. X/* ARGSUSED */
  1896. X
  1897. Xint
  1898. Xether_bcast_self (fd)
  1899. Xint fd;
  1900. X{
  1901. X    return (0);
  1902. X}
  1903. END_OF_FILE
  1904. if test 396 -ne `wc -c <'./src/nit3self.c'`; then
  1905.     echo shar: \"'./src/nit3self.c'\" unpacked with wrong size!
  1906. fi
  1907. # end of './src/nit3self.c'
  1908. fi
  1909. if test -f './src/nit3write.c' -a "${1}" != "-c" ; then 
  1910.   echo shar: Will not clobber existing file \"'./src/nit3write.c'\"
  1911. else
  1912. echo shar: Extracting \"'./src/nit3write.c'\" \(681 characters\)
  1913. sed "s/^X//" >'./src/nit3write.c' <<'END_OF_FILE'
  1914. X/* $Id: nit3write.c,v 2.0 89/10/20 19:02:41 dupuy Exp $ */
  1915. X
  1916. X#include <sys/param.h>
  1917. X#include <sys/socket.h>
  1918. X
  1919. X#include "libether.h"
  1920. X
  1921. Xextern unsigned _ether_types[NOFILE];
  1922. X
  1923. X#define ether_type (_ether_types[fd])
  1924. X
  1925. X/*
  1926. X * Writes a single packet, filling src and type fields.
  1927. X */
  1928. X
  1929. Xint
  1930. Xether_write (fd, packet)
  1931. Xint fd;
  1932. Xether_packet *packet;
  1933. X{
  1934. X    struct sockaddr sa;
  1935. X
  1936. X    sa.sa_family = AF_UNSPEC;
  1937. X    bcopy ((char *) packet, sa.sa_data, ETHER_TYPE);
  1938. X
  1939. X    if (ether_type != ETHER_ALLTYPES)
  1940. X    {
  1941. X    sa.sa_data[12] = (ether_type >> 8) & 0xff;
  1942. X    sa.sa_data[13] = ether_type & 0xff;
  1943. X    }
  1944. X
  1945. X    return (sendto (fd, packet->pktbuf, (int) packet->pktlen, 0, &sa,
  1946. X            sizeof (sa)) < 0 ? -1 : 0);
  1947. X}
  1948. END_OF_FILE
  1949. if test 681 -ne `wc -c <'./src/nit3write.c'`; then
  1950.     echo shar: \"'./src/nit3write.c'\" unpacked with wrong size!
  1951. fi
  1952. # end of './src/nit3write.c'
  1953. fi
  1954. if test -f './src/nit3writev.c' -a "${1}" != "-c" ; then 
  1955.   echo shar: Will not clobber existing file \"'./src/nit3writev.c'\"
  1956. else
  1957. echo shar: Extracting \"'./src/nit3writev.c'\" \(844 characters\)
  1958. sed "s/^X//" >'./src/nit3writev.c' <<'END_OF_FILE'
  1959. X/* $Id: nit3writev.c,v 2.0 89/10/20 19:02:42 dupuy Exp $ */
  1960. X
  1961. X#include <sys/param.h>
  1962. X#include <sys/socket.h>
  1963. X
  1964. X#include "libether.h"
  1965. X
  1966. Xextern unsigned _ether_types[NOFILE];
  1967. X
  1968. X#define ether_type (_ether_types[fd])
  1969. X
  1970. X/*
  1971. X * Writes a single packet, filling src and type fields.
  1972. X */
  1973. X
  1974. Xint
  1975. Xether_writev (fd, packet)
  1976. Xint fd;
  1977. Xether_vec *packet;
  1978. X{
  1979. X    struct sockaddr sa;
  1980. X    struct msghdr msg;
  1981. X
  1982. X    sa.sa_family = AF_UNSPEC;
  1983. X    bcopy ((char *) packet, sa.sa_data, ETHER_TYPE);
  1984. X
  1985. X    if (ether_type != ETHER_ALLTYPES)
  1986. X    {
  1987. X    sa.sa_data[12] = (ether_type >> 8) & 0xff;
  1988. X    sa.sa_data[13] = ether_type & 0xff;
  1989. X    }
  1990. X
  1991. X    msg.msg_iov = packet->iov;
  1992. X    msg.msg_iovlen = packet->iovcnt;
  1993. X    msg.msg_name = (caddr_t) & sa;
  1994. X    msg.msg_namelen = sizeof (sa);
  1995. X    msg.msg_accrights = 0;
  1996. X    msg.msg_accrightslen = 0;
  1997. X
  1998. X    return (sendmsg (fd, &msg, 0) < 0 ? -1 : 0);
  1999. X}
  2000. END_OF_FILE
  2001. if test 844 -ne `wc -c <'./src/nit3writev.c'`; then
  2002.     echo shar: \"'./src/nit3writev.c'\" unpacked with wrong size!
  2003. fi
  2004. # end of './src/nit3writev.c'
  2005. fi
  2006. if test -f './src/nit4intaddr.c' -a "${1}" != "-c" ; then 
  2007.   echo shar: Will not clobber existing file \"'./src/nit4intaddr.c'\"
  2008. else
  2009. echo shar: Extracting \"'./src/nit4intaddr.c'\" \(1809 characters\)
  2010. sed "s/^X//" >'./src/nit4intaddr.c' <<'END_OF_FILE'
  2011. X/* $Id: nit4intaddr.c,v 2.1 89/10/23 15:42:56 dupuy Exp $ */
  2012. X
  2013. X#include <strings.h>            /* strncpy */
  2014. X#include <sys/file.h>            /* O_RDWR */
  2015. X#include <sys/types.h>            /* NIOCBIND (u_long) */
  2016. X#include <sys/time.h>            /* NIOCBIND (timeval) */
  2017. X#include <sys/ioccom.h>            /* ioctl */
  2018. X#include <sys/socket.h>            /* ifreq (sockaddr) */
  2019. X
  2020. X#include <net/if.h>            /* ifreq */
  2021. X#include <net/nit_if.h>            /* NIOCBIND */
  2022. X
  2023. X#include "libether.h"
  2024. X
  2025. Xextern int errno;
  2026. X
  2027. X#ifndef NIT_DEV
  2028. X#define NIT_DEV "/dev/nit"
  2029. X#endif
  2030. X
  2031. Xether_addr _ether_localaddr;        /* shared with ether_address() */
  2032. Xint _ether_haveaddress;            /* shared with ether_address() */
  2033. X
  2034. X/*
  2035. X * Returns the local ethernet address for an ethernet interface.  The result
  2036. X * is stored in the structure given by address; if none is given, malloc is
  2037. X * used to allocate space.  Sun systems have the "feature" that all ethernet
  2038. X * interfaces are set to the same address (taken from the ID PROM).  So we can
  2039. X * get the answer once, and use it forever.
  2040. X */
  2041. X
  2042. Xether_addr *
  2043. Xether_intfaddr (intf, address)
  2044. Xchar *intf;
  2045. Xether_addr *address;
  2046. X{
  2047. X    if (!_ether_haveaddress)
  2048. X    {
  2049. X    int fd;
  2050. X    struct ifreq ifr;
  2051. X    int saved_errno;
  2052. X
  2053. X    if ((fd = open (NIT_DEV, O_RDWR)) < 0)
  2054. X    {
  2055. X#ifdef DEBUG
  2056. X        perror (NIT_DEV);
  2057. X#endif
  2058. X        return (0);
  2059. X    }
  2060. X
  2061. X    (void) strncpy (ifr.ifr_name, intf, sizeof (ifr.ifr_name));
  2062. X
  2063. X    if (ioctl (fd, NIOCBIND, (char *) &ifr) < 0)
  2064. X    {
  2065. X        saved_errno = errno;
  2066. X#ifdef DEBUG
  2067. X        perror ("ether_intfaddr: ioctl NIOCBIND");
  2068. X#endif
  2069. X        (void) close (fd);
  2070. X        errno = saved_errno;
  2071. X        return (0);
  2072. X    }
  2073. X
  2074. X    address = ether_address (fd, address);
  2075. X
  2076. X    saved_errno = errno;
  2077. X    (void) close (fd);
  2078. X    errno = saved_errno;
  2079. X
  2080. X    return (address);
  2081. X    }
  2082. X
  2083. X    if (address == 0)
  2084. X    address = (ether_addr *) malloc (sizeof (ether_addr));
  2085. X
  2086. X    if (address != 0)
  2087. X    *address = _ether_localaddr;
  2088. X
  2089. X    return (address);
  2090. X}
  2091. END_OF_FILE
  2092. if test 1809 -ne `wc -c <'./src/nit4intaddr.c'`; then
  2093.     echo shar: \"'./src/nit4intaddr.c'\" unpacked with wrong size!
  2094. fi
  2095. # end of './src/nit4intaddr.c'
  2096. fi
  2097. if test -f './src/nit4self.c' -a "${1}" != "-c" ; then 
  2098.   echo shar: Will not clobber existing file \"'./src/nit4self.c'\"
  2099. else
  2100. echo shar: Extracting \"'./src/nit4self.c'\" \(894 characters\)
  2101. sed "s/^X//" >'./src/nit4self.c' <<'END_OF_FILE'
  2102. X/* $Id: nit4self.c,v 2.0 89/10/20 19:02:46 dupuy Exp $ */
  2103. X
  2104. X#include <sys/sockio.h>            /* SIOCGETFDSTAT */
  2105. X
  2106. X/*
  2107. X * No standard sun ethernet interface loops back packets.  Early versions of
  2108. X * the streams-based Sun NIT interface don't loopback broadcast packets, but
  2109. X * 4.0.3 and later appear to (although 4.0.3 has bugs).     Since a 4.0 compiled
  2110. X * binary will run on a 4.0.3 system, we can't determine the answer correctly
  2111. X * at compile time.  Since there doesn't seem to be any kernel feature present
  2112. X * in 4.0.3 and absent in earlier versions that we can test for, we use a
  2113. X * compile-time check.    It's the best we can do for now.
  2114. X */
  2115. X
  2116. X/* ARGSUSED */
  2117. X
  2118. Xint
  2119. Xether_send_self (fd)
  2120. Xint fd;
  2121. X{
  2122. X    return (0);
  2123. X}
  2124. X
  2125. X/* ARGSUSED */
  2126. X
  2127. Xint
  2128. Xether_mcast_self (fd)
  2129. Xint fd;
  2130. X{
  2131. X    return (0);
  2132. X}
  2133. X
  2134. X/* ARGSUSED */
  2135. X
  2136. Xint
  2137. Xether_bcast_self (fd)
  2138. Xint fd;
  2139. X{
  2140. X#ifdef SIOCGETFDSTAT
  2141. X    return (1);
  2142. X#else
  2143. X    return (0);
  2144. X#endif
  2145. X}
  2146. END_OF_FILE
  2147. if test 894 -ne `wc -c <'./src/nit4self.c'`; then
  2148.     echo shar: \"'./src/nit4self.c'\" unpacked with wrong size!
  2149. fi
  2150. # end of './src/nit4self.c'
  2151. fi
  2152. if test -f './src/nit4write.c' -a "${1}" != "-c" ; then 
  2153.   echo shar: Will not clobber existing file \"'./src/nit4write.c'\"
  2154. else
  2155. echo shar: Extracting \"'./src/nit4write.c'\" \(956 characters\)
  2156. sed "s/^X//" >'./src/nit4write.c' <<'END_OF_FILE'
  2157. X/* $Id: nit4write.c,v 2.0 89/10/20 19:02:47 dupuy Exp $ */
  2158. X
  2159. X#include <sys/types.h>
  2160. X#include <sys/socket.h>
  2161. X#include <sys/stropts.h>
  2162. X
  2163. X#include "libether.h"
  2164. X
  2165. Xextern unsigned _ether_types[FD_SETSIZE];
  2166. X
  2167. X#define ether_type (_ether_types[fd])
  2168. X
  2169. X/*
  2170. X * Writes a single packet, filling src and type fields.
  2171. X */
  2172. X
  2173. Xint
  2174. Xether_write (fd, packet)
  2175. Xint fd;
  2176. Xether_packet *packet;
  2177. X{
  2178. X    struct sockaddr sa;
  2179. X    struct strbuf cbuf;
  2180. X    struct strbuf dbuf;
  2181. X
  2182. X    sa.sa_family = AF_UNSPEC;
  2183. X    bcopy ((char *) packet, sa.sa_data, ETHER_TYPE);
  2184. X
  2185. X    if (ether_type != ETHER_ALLTYPES)
  2186. X    {
  2187. X    sa.sa_data[12] = (ether_type >> 8) & 0xff;
  2188. X    sa.sa_data[13] = ether_type & 0xff;
  2189. X    }
  2190. X
  2191. X    cbuf.maxlen = cbuf.len = sizeof (sa);
  2192. X    cbuf.buf = (char *) &sa;
  2193. X
  2194. X    /*
  2195. X     * The interface output routines will paste the ether header back onto the
  2196. X     * front of the message.
  2197. X     */
  2198. X
  2199. X    dbuf.len = packet->pktlen;
  2200. X    dbuf.buf = packet->pktbuf;
  2201. X
  2202. X    return (putmsg (fd, &cbuf, &dbuf, 0));
  2203. X}
  2204. END_OF_FILE
  2205. if test 956 -ne `wc -c <'./src/nit4write.c'`; then
  2206.     echo shar: \"'./src/nit4write.c'\" unpacked with wrong size!
  2207. fi
  2208. # end of './src/nit4write.c'
  2209. fi
  2210. if test -f './src/nit4writev.c' -a "${1}" != "-c" ; then 
  2211.   echo shar: Will not clobber existing file \"'./src/nit4writev.c'\"
  2212. else
  2213. echo shar: Extracting \"'./src/nit4writev.c'\" \(1172 characters\)
  2214. sed "s/^X//" >'./src/nit4writev.c' <<'END_OF_FILE'
  2215. X/* $Id: nit4writev.c,v 2.0 89/10/20 19:02:48 dupuy Exp $ */
  2216. X
  2217. X#include <sys/types.h>
  2218. X#include <sys/socket.h>
  2219. X#include <sys/stropts.h>
  2220. X#include <sys/uio.h>
  2221. X
  2222. X#include "libether.h"
  2223. X
  2224. Xextern unsigned _ether_types[FD_SETSIZE];
  2225. X
  2226. X#define ether_type (_ether_types[fd])
  2227. X
  2228. X/*
  2229. X * Writes a single packet, filling src and type fields.
  2230. X */
  2231. X
  2232. Xint
  2233. Xether_writev (fd, packet)
  2234. Xint fd;
  2235. Xether_vec *packet;
  2236. X{
  2237. X    struct sockaddr sa;
  2238. X    struct strbuf cbuf;
  2239. X    struct strbuf dbuf;
  2240. X    char buffer[ETHER_MAX];
  2241. X    char *bufp = buffer;
  2242. X    int count;
  2243. X
  2244. X    sa.sa_family = AF_UNSPEC;
  2245. X    bcopy ((char *) packet, sa.sa_data, ETHER_TYPE);
  2246. X
  2247. X    if (ether_type != ETHER_ALLTYPES)
  2248. X    {
  2249. X    sa.sa_data[12] = (ether_type >> 8) & 0xff;
  2250. X    sa.sa_data[13] = ether_type & 0xff;
  2251. X    }
  2252. X
  2253. X    cbuf.maxlen = cbuf.len = sizeof (sa);
  2254. X    cbuf.buf = (char *) &sa;
  2255. X
  2256. X    dbuf.len = 0;
  2257. X    dbuf.buf = bufp;
  2258. X
  2259. X    for (count = 0; count < packet->iovcnt; count++)
  2260. X    if (packet->iov[count].iov_len)
  2261. X    {
  2262. X        bcopy ((char *) packet->iov[count].iov_base, bufp,
  2263. X           (int) packet->iov[count].iov_len);
  2264. X        bufp += packet->iov[count].iov_len;
  2265. X        dbuf.len += packet->iov[count].iov_len;
  2266. X    }
  2267. X
  2268. X    return (putmsg (fd, &cbuf, &dbuf, 0));
  2269. X}
  2270. END_OF_FILE
  2271. if test 1172 -ne `wc -c <'./src/nit4writev.c'`; then
  2272.     echo shar: \"'./src/nit4writev.c'\" unpacked with wrong size!
  2273. fi
  2274. # end of './src/nit4writev.c'
  2275. fi
  2276. if test -f './src/nitaddr.c' -a "${1}" != "-c" ; then 
  2277.   echo shar: Will not clobber existing file \"'./src/nitaddr.c'\"
  2278. else
  2279. echo shar: Extracting \"'./src/nitaddr.c'\" \(1351 characters\)
  2280. sed "s/^X//" >'./src/nitaddr.c' <<'END_OF_FILE'
  2281. X/* $Id: nitaddr.c,v 2.1 89/10/23 15:43:02 dupuy Exp $ */
  2282. X
  2283. X#include <sys/types.h>            /* ifreq (u_short) */
  2284. X#include <sys/socket.h>            /* ifreq (sockaddr) */
  2285. X#include <net/if.h>            /* ifreq */
  2286. X#include <sys/ioctl.h>            /* SIOCGIFADDR */
  2287. X
  2288. X#include "libether.h"
  2289. X
  2290. Xether_addr _ether_localaddr;        /* shared with ether_intfaddr() */
  2291. Xint _ether_haveaddress;            /* shared with ether_intfaddr() */
  2292. X
  2293. X/*
  2294. X * Returns the local ethernet address for the ethernet interface on the file
  2295. X * descriptor fd.  The result is stored in the structure given by address; if
  2296. X * none is given, malloc is used to allocate space.  Sun systems have the
  2297. X * "feature" that all ethernet interfaces are set to the same address (taken
  2298. X * from the ID PROM).  So we can get the answer once, and use it forever.
  2299. X */
  2300. X
  2301. Xether_addr *
  2302. Xether_address (fd, address)
  2303. Xint fd;
  2304. Xether_addr *address;
  2305. X{
  2306. X    if (!_ether_haveaddress)
  2307. X    {
  2308. X    struct ifreq ifr;
  2309. X
  2310. X    ifr.ifr_addr.sa_family = AF_NIT;
  2311. X    if (ioctl (fd, SIOCGIFADDR, (char *) &ifr) < 0)
  2312. X    {
  2313. X#ifdef DEBUG
  2314. X        perror ("ether_address: ioctl SIOCGIFADDR");
  2315. X#endif
  2316. X        return (0);
  2317. X    }
  2318. X
  2319. X    bcopy (ifr.ifr_addr.sa_data, (char *) &_ether_localaddr,
  2320. X           sizeof (ether_addr));
  2321. X
  2322. X    _ether_haveaddress = 1;
  2323. X    }
  2324. X
  2325. X    if (address == 0)
  2326. X    address = (ether_addr *) malloc (sizeof (ether_addr));
  2327. X
  2328. X    if (address != 0)
  2329. X    *address = _ether_localaddr;
  2330. X
  2331. X    return (address);
  2332. X}
  2333. END_OF_FILE
  2334. if test 1351 -ne `wc -c <'./src/nitaddr.c'`; then
  2335.     echo shar: \"'./src/nitaddr.c'\" unpacked with wrong size!
  2336. fi
  2337. # end of './src/nitaddr.c'
  2338. fi
  2339. if test -f './system' -a "${1}" != "-c" ; then 
  2340.   echo shar: Will not clobber existing file \"'./system'\"
  2341. else
  2342. echo shar: Extracting \"'./system'\" \(1175 characters\)
  2343. sed "s/^X//" >'./system' <<'END_OF_FILE'
  2344. X#!/bin/sh
  2345. X#
  2346. X# Determine the current system platform
  2347. X#
  2348. Xif [ -s /bin/arch -a -s /bin/sun ]; then    # Sun's arch
  2349. X    ARCH=`/bin/arch`
  2350. X
  2351. Xelif [ -s /bin/machine ]; then            # MIPS' machine
  2352. X    ARCH=`/bin/machine`
  2353. X
  2354. Xelif [ -f /bin/vax ] && /bin/vax; then
  2355. X    ARCH=vax
  2356. X
  2357. Xelif [ "`echo /bin/hp*`" != '/bin/hp*' ]; then    # HP's way
  2358. X    { /bin/hp9000s800 && ARCH=hp800; } || \
  2359. X    { /bin/hp9000s500 && ARCH=hp500; } || \
  2360. X    { /bin/hp9000s300 && ARCH=hp300; } || \
  2361. X    { /bin/hp9000s200 && ARCH=hp200; } || \
  2362. X    { /bin/hp300 && ARCH=hp300; } || \
  2363. X    { /bin/hp800 && ARCH=hp800; }        # Utah HP 4.3
  2364. X
  2365. Xelif [ -d /usr/ibm -o -d /vrm ]; then        # IBM AIX or ACIS
  2366. X    ARCH=ibmrt
  2367. X
  2368. Xelif [ -d /NextLibrary ]; then            # Unique to NeXT cubes
  2369. X    ARCH=next
  2370. X
  2371. Xelif [ -d /usr/ucb ]; then            # desperation time
  2372. X    ARCH=vax
  2373. Xfi
  2374. X
  2375. Xcase $ARCH in
  2376. X
  2377. X    hp*)
  2378. X        if [ -f /hp-ux ]; then
  2379. X            OS=hpux
  2380. X        fi;;
  2381. X
  2382. X    ibmrt)
  2383. X        if [ -d /vrm ]; then
  2384. X            OS=aix
  2385. X        fi;;
  2386. X
  2387. X    mips*)
  2388. X        if [ -f /ultrixboot ]; then
  2389. X            ARCH=mipsel
  2390. X            OS=ultrix
  2391. X        fi;;
  2392. X
  2393. X    sun[234])
  2394. X        if [ -f /usr/ucb/logger ]; then
  2395. X            OS=os4
  2396. X        elif [ -d /usr/suntools ]; then
  2397. X            OS=os2
  2398. X        fi;;
  2399. X
  2400. X    next)    OS=mach;;
  2401. X
  2402. X    vax)
  2403. X        if [ -f /ultrixboot ]; then
  2404. X            OS=ultrix
  2405. X        fi;;
  2406. X
  2407. X    *)    ARCH=unknown;;
  2408. X
  2409. Xesac
  2410. X
  2411. Xexec echo $ARCH${OS+-$OS}
  2412. END_OF_FILE
  2413. if test 1175 -ne `wc -c <'./system'`; then
  2414.     echo shar: \"'./system'\" unpacked with wrong size!
  2415. fi
  2416. # end of './system'
  2417. fi
  2418. if test ! -d './tests' ; then
  2419.     echo shar: Creating directory \"'./tests'\"
  2420.     mkdir './tests'
  2421. fi
  2422. echo shar: End of archive 1 \(of 3\).
  2423. cp /dev/null ark1isdone
  2424. MISSING=""
  2425. for I in 1 2 3 ; do
  2426.     if test ! -f ark${I}isdone ; then
  2427.     MISSING="${MISSING} ${I}"
  2428.     fi
  2429. done
  2430. if test "${MISSING}" = "" ; then
  2431.     echo You have unpacked all 3 archives.
  2432.     rm -f ark[1-9]isdone
  2433. else
  2434.     echo You still need to unpack the following archives:
  2435.     echo "        " ${MISSING}
  2436. fi
  2437. ##  End of shell archive.
  2438. exit 0
  2439.